package cn.util.date;


import common.constant.DateConstant;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import cn.util.exception.FormatParseException;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by lin.wei on 2017-07-11.
 */
public class DateUtils {

    @SuppressWarnings("unused")
    private static Logger logger = LoggerFactory.getLogger(DateUtils.class);

    private DateUtils() {

    }

    public static final String BEGIN_TIME = "00:00:00";

    public static final String END_TIME = "23:59:59";

    public static final String LONG_DATE_PATTERN = "yyyy-MM-dd HH:mm:ss";

    public static final String TIME_MINUTE_PATTERN = "HH:mm";

    public static final int MILLISECOND_OF_DAY = 24 * 60 * 60 * 1000;

    public static final int MILLISECOND_OF_HOUR = 60 * 60 * 1000;

    public static final int MILLISECOND_OF_MINUTE = 60 * 1000;

    public static final int MILLISECOND_OF_SECOND = 1000;

    public static final String SHORT_DATE_PATTERN = "yyyy-MM-dd";

    public static final String TIME_PATTERN = "HH:mm:ss";

    public static final String NOT_DILIMITER_TIME_PATTERN = "HHmmss";

    public static final int DAY = 1;

    public static final int HOUR = 2;

    public static final int MINUTE = 3;

    public static final int SECOND = 4;

    private static final int YEAR_LENGTH = 4;

    private static final int MONTH_LENGTH = 2;

    private static final int SHORT_DATE_LENGTH = 10;

    private static final int MIN_DOUBLE_FIGURES = 10;

    private static final int MONTH_NUMBER_OF_YEAR = 12;

    // 第一月为0，第二月为1，以此类推
    private static final int FIRST_MONTH_OF_SECOND_QUARTER = 3;

    private static final int FIRST_MONTH_OF_THIRD_QUARTER = 6;

    private static final int FIRST_MONTH_OF_FORTH_QUARTER = 9;

    private static final int QUARTER_NUMBER_OF_YEAR = 4;

    private static final int MONTH_NUMBER_OF_QUARTER = 3;

    public static long dateToLong(){
        return System.currentTimeMillis()/1000;
    }
    /**
     * 获取月末和月初
     * @return
     */
    public static String[] getBeginEndDate(int year , int month){
        Calendar cal = Calendar.getInstance();
        // 不加下面2行，就是取当前时间前一个月的第一天及最后一天
        cal.set(Calendar.YEAR,year);
        cal.set(Calendar.MONTH, month);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.add(Calendar.DAY_OF_MONTH, -1);
        Date lastDate = cal.getTime();

        cal.set(Calendar.DAY_OF_MONTH, 1);
        Date firstDate = cal.getTime();
        String[] beginEnd = new String[2];
        beginEnd[0] = formatDate(firstDate, "yyyy-MM-dd");
        beginEnd[1] = formatDate(lastDate, "yyyy-MM-dd");
        return beginEnd;
    }

    /**
     * 得到指定月的天数
     * */
    public static int getMonthLastDay(int year, int month)
    {
        Calendar a = Calendar.getInstance();
        a.set(Calendar.YEAR, year);
        a.set(Calendar.MONTH, month - 1);
        a.set(Calendar.DATE, 1);//把日期设置为当月第一天
        a.roll(Calendar.DATE, -1);//日期回滚一天，也就是最后一天
        int maxDate = a.get(Calendar.DATE);
        return maxDate;
    }

    /*
     * 将时间转换为时间戳
     */
    public static String dateToStamp(String s) throws ParseException{
        String res;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = simpleDateFormat.parse(s);
        long ts = date.getTime();
        res = String.valueOf(ts);
        return res;
    }

    /*
     * 将时间戳转换为时间
     */
    public static String stampToDate(String s){
        String res;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        long lt = new Long(s);
        Date date = new Date(lt);
        res = simpleDateFormat.format(date);
        return res;
    }

    /**
     * 一个指定日期n个月后的日期
     *
     * @param date
     * @param month
     * @return
     */
    public static Date getAfterMonth(Date date, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, month);

        return calendar.getTime();
    }


    public static Date getAfterMinute(Date date, int minute){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, minute);
        return calendar.getTime();
    }

    public static String getAfterMonth(String dateStr, String format, int month) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        Date date = null;
        try {
            date = dateFormat.parse(dateStr);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, month);

        return dateFormat.format(calendar.getTime());
    }

    /**
     * 得到日期的天数
     *
     * @param date
     * @return
     */
    public static int getDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_MONTH);

    }

    /**
     *
     * @param date
     * @param month
     * @param day
     * @return
     */
    public static Date getMonthDay(Date date, int month, int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, month);
        calendar.set(Calendar.DAY_OF_MONTH, day);
        return calendar.getTime();
    }

    public static Date getAddMonthDay(Date date, int month, int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, month);
        calendar.add(Calendar.DAY_OF_MONTH, day);
        return calendar.getTime();
    }

    public static Date addDay(Date date, int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, day);
        return calendar.getTime();
    }

    /**
     * 一个指定日期n天后的日期
     *
     * @param date
     * @param
     * @return
     */
    public static Date getAfterDay(Date date, int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, day);

        return calendar.getTime();
    }



    /**
     * 获得当前日期字符串，格式：yyyy-mm-dd
     */
    public static String getNowDate() {
        return getNowDate(SHORT_DATE_PATTERN);
    }

    /**
     * 获得当前日期字符串，
     *
     * @param pattern
     *            日期格式
     * @return
     */
    public static String getNowDate(String pattern) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);

        return simpleDateFormat.format(new Date());
    }

    /**
     * 获得当前年月字符串，格式：yyyy-mm
     */
    public static String getNowMonth() {
        return getNowMonth("-");
    }

    /**
     * 获得当前年月字符串，格式：yyyy separate mm
     *
     * @param separate
     * @return
     */
    public static String getNowMonth(String separate) {
        Calendar calendar = Calendar.getInstance();
        String year = "000" + calendar.get(Calendar.YEAR);
        String month = "0" + (calendar.get(Calendar.MONTH) + 1);
        year = year.substring(year.length() - YEAR_LENGTH);
        month = month.substring(month.length() - MONTH_LENGTH);

        return year + separate + month;
    }

    /**
     * 获得日期之间的间隔天数
     *
     * @param beginDatetime
     * @param endDatetime
     * @return
     * @throws ParseException
     */
    public static int getDayNumberOfInterval(String beginDatetime, String endDatetime) {
        return getDayNumberOfInterval(beginDatetime, endDatetime, LONG_DATE_PATTERN);
    }

    /**
     * 获得日期之间的间隔天数
     *
     * @param beginDatetime
     * @param endDatetime
     * @param pattern
     * @return
     * @throws ParseException
     */
    public static int getDayNumberOfInterval(String beginDatetime, String endDatetime, String pattern) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
        Date beginDatetimeDate;
        Date endDatetimeDate;
        try {
            beginDatetimeDate = simpleDateFormat.parse(beginDatetime);
            endDatetimeDate = simpleDateFormat.parse(endDatetime);
        } catch (ParseException e) {
            throw new FormatParseException(e.getMessage(), e);
        }

        return getDayNumberOfInterval(beginDatetimeDate, endDatetimeDate);
    }

    /**
     * 获得日期字符串
     *
     * @param date
     * @param pattern
     * @return
     */
    public static String formatDate(Date date, String pattern) {
        if (date == null) {
            return "";
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
        return simpleDateFormat.format(date);
    }

    /**
     * 获得日期字符串,格式为yyyy-MM-dd hh:mm:ss
     *
     * @param date
     * @return
     */
    public static String formatDate(Date date) {
        return formatDate(date, LONG_DATE_PATTERN);
    }

    /**
     * 获得日期字符串,格式为yyyy-MM-dd
     *
     * @param date
     * @return
     */
    public static String formatShortDate(Date date) {
        return formatDate(date, SHORT_DATE_PATTERN);
    }

    /**
     * 按指定的格式解析日期字符串
     *
     * @param date
     * @param pattern
     * @return
     * @throws ParseException
     */
    public static Date parse(String date, String pattern) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
        try {
            return simpleDateFormat.parse(date);
        } catch (ParseException e) {
            throw new FormatParseException(e.getMessage(), e);
        }
    }



    /**
     * 按yyyy-MM-dd hh:mm:ss格式解析日期字符串
     *
     * @param date
     * @return
     * @throws ParseException
     */
    public static Date parse(String date) {
        return parse(date, LONG_DATE_PATTERN);
    }

    /**
     * 按yyyy-MM-dd格式解析日期字符串
     * @param date
     * @return
     */
    public static Date parseShort(String date) {
        return parse(date, SHORT_DATE_PATTERN);
    }

    /**
     * 获得日期字符串，格式为yyyy-MM-dd
     *
     * @param date
     * @return
     */
    public static String getDate(Date date) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(LONG_DATE_PATTERN);
        return simpleDateFormat.format(date).substring(0, SHORT_DATE_LENGTH);

    }

    /**
     * 获得时间字符串，格式为hh:mm:ss
     *
     * @param date
     * @return
     */
    public static String getTime(Date date) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(LONG_DATE_PATTERN);
        return simpleDateFormat.format(date).substring(SHORT_DATE_LENGTH + 1);

    }

    /**
     * 获得时间字符串，格式为hh:mm
     *
     * @param date
     * @return
     */
    public static String getShortTime(Date date) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(TIME_MINUTE_PATTERN);
        return simpleDateFormat.format(date);

    }

    /**
     * 获得日期之间的间隔天数
     *
     * @param beginDatetime
     * @param endDatetime
     * @return
     */
    public static int getDayNumberOfInterval(Date beginDatetime, Date endDatetime) {
        long timeInterval = endDatetime.getTime() - beginDatetime.getTime();
//		if (timeInterval < 0) {
//			return 0;
//		}

        return (int) ((timeInterval) / MILLISECOND_OF_DAY);
    }
    public static int getMinuteNumberOfInterval(Date beginDatetime, Date endDatetime) {
        long timeInterval = endDatetime.getTime() - beginDatetime.getTime();

        return (int) ((timeInterval) / MILLISECOND_OF_MINUTE);
    }


    /**
     * 获得日期之间的间隔,格式为 hh:mm:ss
     *
     * @param beginDatetime
     * @param endDatetime
     * @return
     */
    public static String getInterval(Date beginDatetime, Date endDatetime) {
        long timeInterval = endDatetime.getTime() - beginDatetime.getTime();
        if (timeInterval < 0) {
            return "00:00:00";
        }
        long hour = timeInterval / MILLISECOND_OF_HOUR;
        long minute = (timeInterval % MILLISECOND_OF_HOUR) / MILLISECOND_OF_MINUTE;
        long second = (timeInterval % MILLISECOND_OF_HOUR) % MILLISECOND_OF_MINUTE / MILLISECOND_OF_SECOND;
        String hour2 = hour + "";
        if (hour < MIN_DOUBLE_FIGURES) {
            hour2 = "0" + hour;
        }
        String minute2 = minute + "";
        if (minute < MIN_DOUBLE_FIGURES) {
            minute2 = "0" + minute;
        }

        String second2 = second + "";
        if (second < MIN_DOUBLE_FIGURES) {
            second2 = "0" + second;
        }

        return hour2 + ":" + minute2 + ":" + second2;
    }

    private static final Map<Integer, Integer> INTERVAL_MAP;

    static {
        Map<Integer, Integer> intervalMap = new HashMap<Integer, Integer>();
        intervalMap.put(DAY, MILLISECOND_OF_DAY);
        intervalMap.put(HOUR, MILLISECOND_OF_HOUR);
        intervalMap.put(MINUTE, MILLISECOND_OF_MINUTE);
        intervalMap.put(SECOND, MILLISECOND_OF_SECOND);
        INTERVAL_MAP = (Map<Integer, Integer>) Collections.unmodifiableMap(intervalMap);
    }

    /**
     * 获得时间间隔，
     *
     * @param beginDatetime
     * @param endDatetime
     * @param type
     *            间隔单位，取值 DAY，HOUR，MINUTE，SECOND
     * @return
     */
    public static long getInterval(Date beginDatetime, Date endDatetime, int type) {
        long timeInterval = endDatetime.getTime() - beginDatetime.getTime();
        if (timeInterval < 0) {
            return 0;
        }
        return timeInterval / INTERVAL_MAP.get(type);

    }


    private static final Map<Integer, String> QUARTER_MAP;

    static {
        Map<Integer, String> quarterMap = new HashMap<Integer, String>();
        quarterMap.put(0, "一季度");
        quarterMap.put(FIRST_MONTH_OF_SECOND_QUARTER, "二季度");
        quarterMap.put(FIRST_MONTH_OF_THIRD_QUARTER, "三季度");
        quarterMap.put(FIRST_MONTH_OF_FORTH_QUARTER, "四季度");
        QUARTER_MAP = (Map<Integer, String>) Collections.unmodifiableMap(quarterMap);
    }



    /**
     * 获得月底日期
     *
     * @param month
     *            yyyy-MM格式的年月字符串
     * @return
     * @throws ParseException
     */
    public static String getMonthEnd(String month) {
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(SHORT_DATE_PATTERN);
        try {
            calendar.setTime(simpleDateFormat.parse(month + "-01"));
        } catch (ParseException e) {
            throw new FormatParseException(e.getMessage(), e);
        }
        calendar.add(Calendar.MONTH, 1);
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        return simpleDateFormat.format(calendar.getTime());
    }

    /**
     * 获得该季度最后一天
     *
     * @param month
     *            yyyy-MM格式的年月字符串，表示该季度的第一月
     * @return
     * @throws ParseException
     */
    public static String getQuarterEnd(String month) {
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(SHORT_DATE_PATTERN);
        try {
            calendar.setTime(simpleDateFormat.parse(month + "-01"));
        } catch (ParseException e) {
            throw new FormatParseException(e.getMessage(), e);
        }
        calendar.add(Calendar.MONTH, MONTH_NUMBER_OF_QUARTER);
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        return simpleDateFormat.format(calendar.getTime());
    }

    /**
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static int getMonthCount(Date startDate, Date endDate) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        int startYear = calendar.get(Calendar.YEAR);
        int startMonth = calendar.get(Calendar.MONTH);
        calendar.setTime(endDate);
        int endYear = calendar.get(Calendar.YEAR);
        int endMonth = calendar.get(Calendar.MONTH);
        return (endYear - startYear) * 12 + (endMonth - startMonth);
    }

    /**
     * 获得日期之间的天数
     * @param beginDate
     * @param endDate
     * @return
     */
    public static int getDayCountBetweenDate(Date beginDate, Date endDate) {
        return (int)((endDate.getTime() - beginDate.getTime()) / MILLISECOND_OF_DAY);
    }

    /**
     * sql时间当天时间调整从0点到24点查询 add by zzw 2016年12月17日
     * @param stringDateTime
     * @param startOrEnd 0:开始时间 00:00:00  1：结束时间  23:59:59
     * @return
     */
    public static String DateTimeStartOrEnd(String stringDateTime){
        if(stringDateTime==null || stringDateTime==""){
            Calendar c = Calendar.getInstance();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            c.setTime(new Date());
            //c.add(Calendar.MONTH, 1);
            String a = sdf.format(c.getTime());
            stringDateTime = a;
        }
        return stringDateTime;
    }

    /**
     * 获取当前日期时间，格式为yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static String getCurrentDateTimeForm(){
        return dateToStr(new Date(),DateConstant.DATE_TIME_FORMAT);
    }
    /**
     * 获取当前时间，格式为yyyy-MM-dd
     * @return
     */
    public static String getCurrentDateFormat(){
        return dateToStr(new Date(),DateConstant.DATE_FORMAT);
    }

    /**
     * 日期转化格式
     * @param format
     * @return
     */
    public static String dateToStr(Date date,String format){
        return new DateTime(date).toString(format);
    }

    /**
     * 字符串转化为日期
     * @param date
     * @param format
     * @return
     */
    public static Date strToDate(String date,String format){
        DateTimeFormatter dateTimeFormat = DateTimeFormat.forPattern(format);
        return dateTimeFormat.parseDateTime(date).toDate();
    }

    /**
     * 获取当前时间
     * @return
     */
    public static Date getCurrentDate(){
        return new DateTime().toDate();
    }
    /**
     * 日期转化为Long
     * @return
     */
    public static Long nowDateToLong(){
        return new DateTime().getMillis()/1000;
    }
    public static void main(String args[]) {
        System.out.println(DateUtils.strToDate("2015-12-12 12:12:12","yyyy-MM-dd"));

        int beginEnd =getMonthLastDay(2015, 2);
        System.out.println(beginEnd);
    }
}
